﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace RoiControllers
{
    /// <summary> 形状基类  </summary>
    public abstract class ShapeBase:ShapeUpdateEvents
    {
        #region 字段、属性
        #region 字段
        private string _name = "形状";               //形状名称
        private string _description = "形状描述";    //形状描述
        protected Color _backColor = Color.Blue;     //填充颜色
        protected Color _handleColor = Color.Orange; //手柄颜色
        protected Color _selectedColor = Color.Blue; //选中时的颜色
        protected float _borderWidth = 0;            //边缘线宽
        protected byte _alpha = 50;                  //透明度            
        protected int _handleSize = 8;               //手柄的视觉大小
        protected int _handleOutSize = 16;           //手柄外区域大小(比视觉大)
        protected bool _isSelected = true;           //选中状态
        protected PointF _location = PointF.Empty;   //位置
        protected ShapeType _type = ShapeType.None;  //形状类型   
        private ShapeHandleType _handleType = ShapeHandleType.None;
        private bool isRotating = false;             //是否旋转
        #endregion

        #region 属性
        /// <summary> 形状名称 </summary>
        [Category("用户属性")]
        [Description("形状名称")]
        public string Name { get => _name; set => _name = value; }
        /// <summary> 形状描述 </summary>
        [Category("用户属性")]
        [Description("形状描述")]
        public string Description { get => _description; set => _description = value; }
        /// <summary> 形状填充的背景颜色 </summary>
        [Category("用户属性")]
        [Description("形状填充的背景颜色")]
        public Color BackColor { get => _backColor; set => _backColor = value; }
        /// <summary> 形状手柄填充的颜色 </summary>
        [Category("用户属性")]
        [Description("形状手柄填充的颜色")]
        public Color HandleColor { get => _handleColor; set => _handleColor = value; }
        /// <summary> 选中形状时填充的颜色 </summary>
        [Category("用户属性")]
        [Description("选中形状时填充的颜色")]
        public Color SelectedColor { get => _selectedColor; set => _selectedColor = value; }
        /// <summary> 边缘线宽</summary>
        [Category("用户属性")]
        [Description("边缘线宽")]
        public float BorderWidth { get => _borderWidth; set => _borderWidth = value; }
        /// <summary> 透明度</summary>
        [Category("用户属性")]
        [Description("透明度")]
        public byte Alpha { get => _alpha; set => _alpha = value; }
        /// <summary> 手柄大小</summary>
        [Category("用户属性")]
        [Description("手柄大小")]
        public int HandleSize
        {
            get => _handleSize;
            set
            {
                if (_handleSize != value)
                {
                    _handleSize = value;
                    HandleOutSize = value * 2;
                }
            }
        }
        /// <summary> 手柄扩增后大小</summary>
        [Category("用户属性")]
        [Description("手柄扩增后大小")]
       
        public int HandleOutSize
        {
            get => _handleOutSize;
            set
            {
                if (_handleOutSize != value)
                {
                    _handleOutSize = value;
                    _handleSize = value / 2;
                }
            }
        }
        [Category("用户属性")]
        [Description("形状描述")]
        /// <summary> 选中状态</summary>
        public bool IsSelected
        {
            get => _isSelected;
            set
            {
                if (_isSelected != value)
                {
                    _isSelected = value;
                    //SelectedColor = _isSelected ? Color.Red : Color.Blue;
                }
            }
        }
        /// <summary> 最后位置 </summary>
        [Category("用户属性")]
        [Description("最后位置")]
        public PointF LastLocation { get => _location; set => _location = value; }
        /// <summary> 形状类型 </summary>
        [Category("用户属性")]
        [Description("形状类型")]
        public ShapeType Type { get=> _type; set => _type = value; }
        /// <summary> 旋转使能 </summary>
        [Category("用户属性")]
        [Description("旋转使能")]
        public bool IsRotating { get => isRotating; set => isRotating = value; }
        public ShapeHandleType HandleType { get => _handleType; set => _handleType = value; }
        #endregion

        #region 事件方法
        /// <summary> 执行选中方法 </summary>
        public abstract void ExceteSelectedCallback(ShapeBase obj);
        /// <summary> 执行移动方法 </summary>
        public abstract void ExceteMoveCallback(ShapeBase obj);
        /// <summary> 执行旋转方法 </summary>
        public abstract void ExceteRotateCallback(ShapeBase obj);
        /// <summary> 执行调整大小方法 </summary>
        public abstract void ExceteResizeCallback(ShapeBase obj);
        /// <summary> 执行附加方法 </summary>
        public abstract void ExceteAttachCallback(ShapeBase obj);
        /// <summary> 执行移除方法 </summary>
        public abstract void ExceteDetachCallback(ShapeBase obj);
        #endregion
        #endregion

        #region 构造函数
        protected ShapeBase()
        {

        }
        protected ShapeBase(PointF point,int radius)
        {

        }
        protected ShapeBase(int x,int y,int width,int height)
        {

        }
        protected ShapeBase(double x, double y, double width, double height,double angle)
        {

        }
        #endregion

        #region
        #endregion
        /// <summary> 获取类型形状，输出形状数据 </summary>
        public void GetTypeShape(ShapeType type,out double[] data)
        {
            switch (type)
            {
                case ShapeType.Rectangle:
                    data = new double[4];
                    URectangle rectangle = this as URectangle;
                    data[0] = rectangle.X;
                    data[1] = rectangle.Y;
                    data[2] = rectangle.Width;
                    data[3] = rectangle.Height;
                    return ;
                case ShapeType.Rectangle2:
                    data = new double[5];
                    URectangle2 rectangle2 = this as URectangle2;
                    data[0] = rectangle2.X;
                    data[1] = rectangle2.Y;
                    data[2] = rectangle2.Width;
                    data[3] = rectangle2.Height;
                    data[4] = rectangle2.RotationAngle;
                    return;
                case ShapeType.Circle:
                    data = new double[3];
                    URCircle circle = this as URCircle;
                    data[0] = circle.Center.X;
                    data[1] = circle.Center.Y;
                    data[2] = circle.Radius;
                    return;
                case ShapeType.Ellipse:
                    data = new double[5];
                    return;
                case ShapeType.Polygon:
                    data = new double[5];
                    return;
                case ShapeType.None:
                    data = new double[5];
                    return;
                default:
                    throw new ArgumentException("Unknown shape type");
            }
        }
        /// <summary> 获取类型形状，返回对应形状对象实例 </summary>
        public T GetTypeShape<T>(ShapeType type) where T : ShapeBase
        {
            try
            {
                return this as T;
            }
            catch (Exception)
            {
                throw new ArgumentException("Unknown shape type");
            }
        }

        #region 抽象方法：绘制形状相关方法。
        /// <summary> 调整形状角度 </summary>
        public abstract void Rotate(PointF point);
        /// <summary> 调整形状位置 </summary>
        public abstract void Move(PointF point);
        /// <summary> 调整形状大小 </summary>
        public abstract void Resize(PointF point);
        /// <summary> 绘制形状带手柄：选中时绘制手柄，未选中时绘制轮廓 </summary>
        public abstract void DrawShapeWithHandle(Graphics graphics);
        /// <summary>绘制形状手柄 </summary>
        public abstract void DrawHandle(Graphics graphics, int x, int y);
        /// <summary>绘制形状手柄 </summary>
        public abstract void DrawHandle(Graphics graphics, float x, float y);
        /// <summary>绘制形状手柄 </summary>
        public abstract void DrawHandle(Graphics graphics, PointF point);
        /// <summary> 获取要显示的自定义手柄类型：根据输入点</summary>
        public abstract ShapeHandleType GetHandleType(PointF point);
        /// <summary> 获取系统自带的手柄类型：根据输入点 </summary>
        public abstract Cursor GetSystemHandleType(PointF point);
        /// <summary> 输入点是否在矩形区域内 </summary>
        public abstract bool IsInRegion(PointF point);
        /// <summary> 输入点是否在矩形背景区域内（仅背景，不包括手柄交集） </summary>
        public abstract bool IsInBackground(PointF point);
        /// <summary> 输入点是否在手柄范围内（输入点，所在点（中心）） </summary>
        public abstract bool IsInHandle(PointF inPoint, PointF point);
        /// <summary> 输入点是否在旋转手柄范围内 </summary>
        public abstract bool IsInRotateHandle(PointF point);
        #endregion

    }
    /// <summary> 手柄类型 </summary>
    public enum ShapeHandleType
    {
        None,
        [Description("旋转")]
        Rotation,
        [Description("中心")]
        Center,
        [Description("内部")]
        Inner,
        [Description("左")]
        Left,
        [Description("上")]
        Top,
        [Description("右")]
        Right,
        [Description("下")]
        Bottom,
        [Description("左上")]
        TopLeft,
        [Description("右上")]
        TopRight,
        [Description("左下")]
        BottomLeft,
        [Description("右下")]
        BottomRight
    }
    /// <summary> 形状类型  </summary>
    public enum ShapeType
    {
        [Description("矩形")]
        Rectangle,
        [Description("方向矩形")]
        Rectangle2,
        [Description("圆形")]
        Circle,
        [Description("椭圆形")]
        Ellipse,
        [Description("多边形")]
        Polygon,
        [Description("None")]
        None
    }
    /// <summary> 形状操作模式 </summary>
    public enum ShapeOperateMode
    {
        None,
        [Description("绘制")]
        Drawing,
        [Description("选中")]
        Selected,
        [Description("移动")]
        Move,
        [Description("大小")]
        Resize,
        [Description("缩放")]
        Scaled,
        [Description("旋转")]
        Rotote,
    }
}
